package com.whynot.frame.basic.mybatis.conroller;

import com.whynot.frame.basic.common.model.APIBase;
import com.whynot.frame.basic.mybatis.conroller.model.Page;
import com.whynot.frame.basic.mybatis.model.BaseModel;
import com.whynot.frame.basic.mybatis.service.BaseServiceImpl;
import com.whynot.frame.basic.util.DateUtils;
import com.whynot.frame.basic.util.Reflections;
import com.whynot.frame.basic.util.StringUtils;
import com.whynot.frame.basic.util.WebUtil;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import javax.servlet.http.HttpServletRequest;



/**
 * 描述: 基础的增删查改接口:
 * 作者: chenyao
 * 日期: 2018-01-30.
 * 项目名称: curtain-whynot-basic-mybatis
 * 版本: 1.0.0
 * JDK: since 1.8
 */
public abstract class BaseTableController<M extends BaseServiceImpl, T extends BaseModel> {

    @Autowired
    protected M service;

    /**
     *  通用的表格查询方法，自带分页，如果不能满足可以实现beforeShowList进行自定义查询分页,结果统一返回
     *  支持属性名和字段名查询,两种方式都可以，自动识别，不区分大小写，默认小写)
     * @param p 分页对象
     * @param t 用户对象
     * @return APIBase
     */
    @ApiOperation(value = "通用的表格查询方法", notes = "通用的表格查询方法", response = APIBase.class)
    @RequestMapping(value = "/showList" ,method = RequestMethod.GET)
    public APIBase showList(@ModelAttribute Page p,@ModelAttribute T t){
        APIBase result=new APIBase();
        try{
            com.baomidou.mybatisplus.plugins.Page<T> page = this.service.getPageCollection(p,t);
            result.setData(new Page(page.getSize(),page.getPages(),page.getTotal(),page.getCurrent(),page.getRecords()));
            result.setSuccess(true);
            this.service.afterShowList(result);
        }catch(Exception e){
            result.setSuccess(false);
            result.setMsg("查询分页出错!");
        }
        return result;
    }

    /**
     * 描  述:通用的增加或者更新
     * 参  数:param 参数为属性名和值
     * 返回值: com.whynot.frame.basic.common.model.APIBase
     * 创建时间: 2018/5/17
     */
    @ApiOperation(value = "通用的增加或者更新方法", notes = "通用的增加或者更新方法", response = APIBase.class)
    @RequestMapping(value = "/saveOrUpdate",method = RequestMethod.POST )
    public APIBase saveOrUpdate(@ModelAttribute T t,HttpServletRequest request){
        APIBase result=new APIBase();
        try{
            result.setSuccess(true);
            String id = BeanUtils.getProperty(t,"id");

            T entity;
            //增加
            if(StringUtils.isEmpty(id)){
                Class<T>cls= Reflections.getClassGenricType(getClass(),1);
                entity=cls.newInstance();

                if(BaseModel.class.isAssignableFrom(entity.getClass())){
                    entity.setCreateTime(DateUtils.getCurrentDateTimeAsString());
                    entity.setLastModifyTime(DateUtils.getCurrentDateTimeAsString());
                    String userId = entity.getCreator() == null
                            ? WebUtil.getUserName(request)
                            : entity.getCreator();
                    entity.setCreator(userId);
                }
            }else{
                //修改
                entity= (T) this.service.selectById(id);
                if(entity!=null && BaseModel.class.isAssignableFrom(entity.getClass())){
					entity.setLastModifyTime(DateUtils.getCurrentDateTimeAsString());
					String userId = entity.getLastModify() == null
							? WebUtil.getUserName(request)
							: entity.getLastModify();
					entity.setLastModify(userId);
				}
            }

            String idKey = BeanUtils.getProperty(t,"id");
            BeanUtils.copyProperties(entity,t);
            if(idKey!=null){
                BeanUtils.copyProperty(t,"id",idKey);
            }

            // 扩展点，保存之前可以针对对象进行操作
           this.service.beforeSaveUpdate(entity,t);
            this.service.insertOrUpdate(entity);
            result.setData(entity);
            this.service.afterSaveUpdate(entity,t);
        }catch(Exception e){
            result.setSuccess(false);
            result.setMsg("保存出错!");
        }
        return result;
    }



    /**
     * 描  述:通用的删除方法
     * 参  数:param
     * 返回值: com.whynot.frame.basic.common.model.APIBase
     * 创建时间: 2018/5/17
     */
    @ApiOperation(value = "通用的删除操作", notes = "通用的删除操作", response = APIBase.class)
    @RequestMapping(value = "/delete" ,method = RequestMethod.GET)
    public APIBase delete(
            @ApiParam(name = "id",value = "用户名",required = true) @RequestParam(value = "id") Integer id
    ){
        APIBase result=new APIBase();
        try{
            result.setSuccess(true);
            this.service.deleteById(id);
            this.service.afetrDelete(id);
        }catch(Exception e){
            result.setSuccess(false);
            result.setMsg("删除出错!");
        }
        return result;
    }

    @ApiOperation(value = "通用的更新之前取数据操作", notes = "通用的更新之前取数据操作", response = APIBase.class)
    @RequestMapping(value = "/showUpdate",method = RequestMethod.GET )
    public APIBase showUpdate(
            @ApiParam(name = "id",value = "用户名",required = true) @RequestParam(value = "id") Integer id
    ){
        APIBase result=new APIBase();
        try{
            result.setSuccess(true);
            T entity= (T) this.service.selectById(id);
            this.service.beforeShowUpdate(entity);
            result.setData(entity);
        }catch(Exception e){
            result.setSuccess(false);
            result.setMsg("获取信息出错!");
        }
        return result;
    }
}